#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2018-2021 Arm Limited.
# SPDX-License-Identifier: Apache-2.0
#

# Top level build script for Ethos-N driver stack
# - reuse variable definitions across sub-module builds
# - remove duplication

from __future__ import print_function
import os
from SCons.Node.Alias import default_ans
import common


Help(
    """
Usage:
    See README.md and the Software Integration guide.

Variables:
"""
)

var = common.create_variables()

var.AddVariables(
    BoolVariable("debug", "Build in debug instead of release mode", False),
    BoolVariable("tests", "Build UnitTests. Use target 'unit-tests' to execute", False),
    EnumVariable(
        "asserts",
        "Enable asserts. 'debug' means it is enabled if 'debug=1'",
        "debug",
        allowed_values=("0", "1", "debug"),
    ),
    BoolVariable("sanitize", "Build with sanitizers for gcc", False),
    EnumVariable(
        "platform",
        'Build for a given platform. An Android build option "android-ndk" is present in the '
        + "build system, however the build for Android platforms is not currently officially supported.",
        "native",
        allowed_values=("native", "aarch64", "android-ndk"),
    ),
    PathVariable("build_dir", "Build output directory", "build", PathVariable.PathIsDirCreate),
    ("device_node_prefix", "Device node prefix in the dev filesystem", "/dev/ethosn"),
    ("device_node_base_id", "Valid device node identifier in the dev filesystem", "0"),
    (
        "firmware_profiling_node",
        "Firmware profiling node in the sys filesystem",
        "/sys/kernel/debug/ethosn0/core0/firmware_profiling",
    ),
    BoolVariable(
        "allow_command_stream_dump",
        "Build the driver library with the ability to dump command streams. "
        "This requires additional build-time dependencies.",
        False,
    ),
    BoolVariable("werror", "Build with -Werror", True),
    PathVariable(
        "android_ndk_dir",
        "Android NDK directory, used only if platform=android-ndk",
        "",
        PathVariable.PathAccept,
    ),
)

env = Environment(variables=var)

Help(var.GenerateHelpText(env))
# Parse the default variables which were setup by common.create_variables()
common.parse_default_vars(env)

# Top level assumes knowledge of the different components locations
env["driver_library_dir"] = "driver_library"
env["support_library_dir"] = "support_library"
env["command_stream_dir"] = os.path.join(env["support_library_dir"], "command_stream")
env["utils_dir"] = "utils"
env["lib_xml_to_binary_dir"] = os.path.join(env["command_stream_dir"], "xml_to_binary")

# These can be overridden by developer options, if applicable
env["kernel_module_dir"] = os.path.join("..", "kernel-module")
env["target"] = "kmod"

# Because these path arguments may be relative, they must be correctly interpreted as relative to the top-level
# folder rather than the 'build' subdirectory, which is what scons would do if they were passed to the SConscript
# files as-is. Therefore we convert them to absolute paths here, where they will be interpreted correctly.
common.abs_path(
    env,
    [
        "command_stream_dir",
        "driver_library_dir",
        "support_library_dir",
        "utils_dir",
        "lib_xml_to_binary_dir",
        "kernel_module_dir",
    ],
)

# Avoid building extra components by default, e.g. libXmlToBinary
Default(
    common.get_driver_library_build_dir(env),
    common.get_support_library_build_dir(env),
    common.get_command_stream_build_dir(env),
)


Export("env")
common.load_extras(env)

# Process all modules which use a variant_dir
# We're going to clone this, in the current form, some modules are polluting the env, breaking subsequent builds.
env_backup = env

env = env_backup.Clone()
SConscript(
    dirs=[env["driver_library_dir"]],
    variant_dir=common.get_driver_library_build_dir(env),
    duplicate=False,
    exports="env",
)

env = env_backup.Clone()
SConscript(
    dirs=[env["support_library_dir"]],
    variant_dir=common.get_support_library_build_dir(env),
    duplicate=False,
    exports="env",
)

env = env_backup.Clone()
SConscript(
    dirs=[env["command_stream_dir"]],
    variant_dir=common.get_command_stream_build_dir(env),
    duplicate=False,
    exports="env",
)

env = env_backup.Clone()
SConscript(
    dirs=[env["utils_dir"]],
    variant_dir=common.get_utils_build_dir(env),
    duplicate=False,
    exports="env",
)

env = env_backup.Clone()
SConscript(
    dirs=[env["lib_xml_to_binary_dir"]],
    variant_dir=common.get_lib_xml_to_binary_build_dir(env),
    duplicate=False,
    exports="env",
)

aliases = default_ans.keys()
env.Help("\n")
env.Help("Found targets: \n")
for alias in sorted(aliases):
    env.Help("    {}\n".format(alias))
